home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c)Copyright 1992-1997 Obvious Implementations Corp. Redistribution and
- * use is allowed under the terms of the DICE-LICENSE FILE,
- * DICE-LICENSE.TXT.
- */
- /*
- * $Id: bintohex.c,v 30.326 1995/12/24 06:12:59 dice Exp dice $
- *
- * bintohex infile [outfile]
- *
- * (Was) compilable on an IBM-PC or Amiga _fmode is for Lattice C on the IBM,
- * is IGNORED by Aztec C on the Amiga. Note that INT and CHAR are not
- * used as ibm's lattice C uses 16 bit ints and unsigned chars. Change
- * as needed. No guarentees for the IBMPC version.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <lib/version.h>
-
- IDENT("bintohex",".2");
- DCOPYRIGHT;
-
- #ifdef IBM
- typedef char ubyte;
- typedef unsigned uword;
- typedef int void;
- #else
- typedef unsigned char ubyte;
- typedef unsigned short uword;
- #endif
-
- #define PERLINE 16
-
- void exiterr (ubyte *);
- void convert (int, FILE *, FILE *, unsigned long);
- uword getwlh (FILE *);
- ubyte puth (ubyte, FILE *);
-
- uword _fmode = 0;
-
- int
- main(int ac, char **av)
- {
- char format=1; /* 'i'=Intel. 1,2,3 = Motorola S1-S3 formats. */
- FILE *infile;
- FILE *outfile;
- char *inName=0;
- char *outName=0;
- int i;
- unsigned long org=0; /* Hex file origin */
-
- _fmode = 0x8000;
- if (ac == 1 || ( ac == 2 && *av[1]=='?' ) ) {
- puts(Ident);
- puts(DCopyright);
- puts("bintohex <infile> -o [outfile] -s[1,2,3] [-i] [-O offset]");
- puts("; Convert <infile> to Motorola or Intel Hex format");
- exit(5);
- }
-
- for (i = 1; i < ac; ++i) {
- char *ptr = av[i];
- char *dummy;
-
- if (*ptr != '-') {
- inName = ptr;
- continue;
- }
- ptr += 2;
- switch(ptr[-1]) {
- case 'o':
- if (*ptr == 0) /* Space is optional */
- ptr = av[++i];
-
- outName = ptr;
- break;
- case 'i':
- case 'I':
- format='i';
- break;
- case 's':
- case 'S':
- format=*ptr-'0';
- if (format<1 || format >3) {
- printf("Format %s not supported. Use S1, S2 or S3.\n",av[i]);
- exit(10);
- }
- break;
- case 'O':
- if (*ptr == 0)
- ptr = av[++i];
- org = strtol(ptr, &dummy, 0);
- break;
- default:
- printf("Bad option: %s\n", av[i]);
- exit(10);
- }
- }
-
- if(!inName) {
- printf("No input file specified\n");
- exit(10);
- }
- infile = fopen(inName, "r");
- if (infile == NULL) {
- printf("Unable to open input file %s\n",inName);
- exit(10);
- }
- outfile = (outName) ? fopen(outName, "w") : stdout;
- if (outfile == NULL) {
- printf("Unable to open output file %s\n",outName);
- exit(10);
- }
- convert(format, infile, outfile, org);
- putc('z'&0x1F, outfile); /* ^Z as end of file marker (for BP programmer) */
- fclose(infile);
- fclose(outfile);
- return(0);
- }
-
-
- /*
- * Intel Hex output (MCS80 format):
- *
- * :lloooott(ll bytes hex code)cc ll=# of bytes
- * oooo=origin (high/low format)
- * tt="record type"
- * (00=norm,01=end,02=extended,03=code start)
- * cc=invert of checksum all codes
- * <cr/lf> after each line
- *
- * Extended Intel Hex (MCS-86 format). Adds segment: 20 bits, 1 Megabyte:
- * :ll0000ffaaaass ll-# of bytes (set to 02)
- * ff-format type (set to 02)
- * aaaa-segment offset (address/16)
- * ss-checksum
- *
- *
- * Motorola Hex files:
- * Sxnn[[[aaaa]aa]aa]dd..ddss
- * x =Type 1=4 byte address, 64KB limit
- * Type 2=6 byte address, 16MB limit
- * Type 3=8 byte address, 4 GB limit
- * nn =Number of bytes+3
- * aaaa =address
- * dd..dd =Data
- * ss =Checksum
- *
- */
- void
- convert(format, in, out, org)
- int format;
- FILE *in;
- FILE *out;
- unsigned long org;
- {
- uword idx;
- unsigned long len;
- ubyte buf[256];
-
- fseek(in, 0L, 2); /* Seek to end of file */
- len = ftell(in);
- fseek(in, 0, 0);
-
- if(format == 'i') {
- /************************ Intel **********************************/
- for (;;) {
- while (len > 0) {
- register ubyte chk;
- register short i;
-
- idx = (len > PERLINE) ? PERLINE : len;
- fread(buf, idx, 1, in);
- putc(':', out);
- puth((ubyte)idx, out);
- puth((ubyte)(org >> 8), out);
- puth((ubyte)(org & 0xFF), out);
- putc('0', out);
- putc('0', out);
- chk = idx + (org >> 8) + (org & 0xFF);
- for (i = 0; (uword)i < idx; ++i) {
- chk += buf[i];
- puth(buf[i], out);
- }
- puth((ubyte)-chk, out);
- putc('\r', out);
- putc('\n', out);
- len -= idx;
- org += idx;
- }
- break;
- }
- fprintf(out, ":00000001FF\r\n");
- /* End Intel */
- } else {
- /*********************** Motorola ********************************/
-
- /*
- if(format==1)
- if(len > 0xFFFF)
- printf("Warning: file size greater than 64K S1 limit. Use S2\n");
- if(format==2)
- if(len > 0xFFFFFF)
- printf("Warning: file size greater than 16Mb S2 limit. Use S3\n");
- */
-
- for (;;) {
- while (len > 0) {
- register ubyte chk;
- register short i;
-
- idx = (len > PERLINE) ? PERLINE : len;
- fread(buf, idx, 1, in);
-
- putc('S', out);
- putc(format+'0',out);
-
- puth((ubyte)idx+2+format, out);
-
- chk=idx+2+format;
- if(format==3) {
- chk += puth((ubyte)(org >>24), out);
- chk += puth((ubyte)(org >>16), out);
- }
- if(format==2) {
- chk += puth((ubyte)(org >>16), out);
- }
- chk += puth((ubyte)(org >> 8), out);
- chk += puth((ubyte)(org & 0xFF), out);
-
- for (i = 0; (uword)i < idx; ++i) {
- chk += puth(buf[i], out);
- }
- puth((ubyte)0xff-chk, out);
- putc('\r', out);
- putc('\n', out);
- len -= idx;
- org += idx;
- }
- break;
- }
- fprintf(out, "S%c\r\n",10-format+'0'); /* S9,S8,S7 */
- } /* End Motorola */
- }
-
- uword
- getwlh(in)
- FILE *in;
- {
- uword result;
-
- result = getc(in);
- result += getc(in) << 8;
- return(result);
- }
-
- ubyte puth(ubyte c, FILE *out)
- {
- static ubyte dig[] = { "0123456789ABCDEF" };
- putc(dig[(c>>4)&15], out);
- putc(dig[c&15], out);
- return(c);
- }
-